package com.pingbu.tijian.hospital.backapi.service;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pingbu.common.bean.ResultBean;
import com.pingbu.common.utils.PbFileUtils;
import com.pingbu.common.utils.PbSecretUtils;
import com.pingbu.tijian.hospital.backapi.bean.entity.*;
import com.pingbu.tijian.hospital.backapi.bean.vo.FullTableStudentZuoye;
import com.pingbu.tijian.hospital.backapi.config.GlobalConst;
import com.pingbu.tijian.hospital.backapi.config.GlobalSet;
import com.pingbu.tijian.hospital.backapi.mapper.*;
import org.apache.catalina.User;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

@Service
public class StudentZuoyeService {

    private static Logger logger = LoggerFactory.getLogger(StudentZuoyeService.class);

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private StudentGroupMapper studentGroupMapper;
    @Autowired
    private BuzhiZuoyeMapper buzhiZuoyeMapper;
    @Autowired
    private StudentZuoyeMapper studentZuoyeMapper;
    @Autowired
    private GlobalSet globalSet;
    @Autowired
    private UserPermissionMapper userPermissionMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private RevertMapper revertMapper;


    /**
     * 刷新一个布置作业 与 相关学生的关系
     * @return
     */
    public ResultBean<Integer> refreshByBuzhiZuoyeId(String buzhiZuoyeId){

        // 1 根据布置作业id 获取布置作业对象
        if(StringUtils.isEmpty(buzhiZuoyeId)){
            return ResultBean.create(24,"参数 buzhiZuoyeId 不允许为空. ");
        }

        BuzhiZuoye bzzy = new BuzhiZuoye();
        bzzy.setNoid(buzhiZuoyeId);

        BuzhiZuoye bzzy2 = buzhiZuoyeMapper.get(bzzy);

        if(bzzy2 ==null){
            return ResultBean.create(23,"未能获得noid=="+buzhiZuoyeId+"的布置作业。");
        }

        // 2 读取该布置布置作业 下已经分配的所有学生关系记录
        StudentZuoye stzy1= new StudentZuoye();
        stzy1.setBuzhi_zuoye_id(buzhiZuoyeId);
        // 李子阳 组完善的代码
        List<StudentZuoye> stzy2Lst = studentZuoyeMapper.list(stzy1);

        // 2.1 为了查找速度，将 stzy2Lst 转为 stzy2Map
        Map<String, StudentZuoye> stzy2Map = new HashMap<>();
        for(StudentZuoye stzy3: stzy2Lst){
            /**
             *  将 布置作业id和 学生id 拼接为一个字符串，作为 map的key
             *  为了防止key过长，进行md5处理为32个字符长度
             */
            String stzykey = PbSecretUtils.md5(stzy3.getBuzhi_zuoye_id()+"_"+stzy3.getStudent_id() );
            stzy2Map.put(stzykey,stzy3);

        }

        // 3 读取所有学生的列表
        Student st1 = new Student();
        List<Student> st1Lst = studentMapper.list(st1);

        /**
         * 4 遍历所有的学生 st1Lst ，并验证是否已经在 stzy2Lst中了
         *  如果已经存在， 就更新
         *  如果还不存在， 就新增
          */
        for(Student st4: st1Lst){
            String stzy4key =PbSecretUtils.md5( buzhiZuoyeId+"_"+st4.getNoid() );

            StudentZuoye stzy4 = null;
            // 如果 map中存在该key，说明只需要更新数据记录
            if(stzy2Map.containsKey(stzy4key)){
                stzy4 = stzy2Map.get(stzy4key);
            }
            // 否则就是不存在，需要新增
            else{
                stzy4 = new StudentZuoye();
                stzy4.setNoid(PbSecretUtils.uuid());
                stzy4.setWancheng_status(GlobalConst.Student_Zuoye_Wancheng_Status_No_Exam);
            }

            stzy4.setStudent_id(st4.getNoid());
            stzy4.setStudent_group_id(st4.getStudent_group_id());
            stzy4.setStudent_realname(st4.getStudent_realname());
            stzy4.setBuzhi_zuoye_id(buzhiZuoyeId);
            stzy4.setBuzhi_zuoye_title(bzzy2.getZuoye_title());
            stzy4.setBuzhi_date(bzzy2.getBuzhi_date());
            stzy4.setStudent_order_numb(st4.getOrder_numb());

            // 根据不同状态，进行数据的新增或更新
            if(!stzy2Map.containsKey(stzy4key)){
                studentZuoyeMapper.insert(stzy4);
            }
            else{
                studentZuoyeMapper.update(stzy4);
            }

        }


        return ResultBean.create(0,"success");

    }

    /**
     * 对简单登记列表进行分页
     * @param param
     * @return
     */
    public ResultBean<PageInfo<StudentZuoye>> pageForSimpleDengji(StudentZuoye param){
        List<StudentZuoye> lst2 = null;
        Student student = new Student();
        List<Student> stuList = studentMapper.list(student);

        UserPermission userPermission = new UserPermission();
        userPermission.setUser_id(param.getUserInfoId());
        List<UserPermission> lstPro = userPermissionMapper.list(userPermission);

        if(lstPro.size() == 0){
            for(Student stu : stuList){
                if( stu.getBind_usercode() != null &&stu.getBind_usercode().equals(param.getUsercode())){
                    param.setStudent_id(stu.getNoid());
                    break;
                }
            }
        }

        //先拿到一次满足searkey条件的记录
        List<StudentZuoye> lst3 = studentZuoyeMapper.list(param);
        //当前页-1*12
        int countNumb = (param.getPageNum()-1)*param.getPageSize();

        //判断搜索条件不为null lst3的长度<=当前的页数-1*12
        if(param.getSearchKey() != null && !"".equals(param.getSearchKey()) && lst3.size()<=countNumb){
            param.setPageNum(1);
        }
        PageHelper.startPage(param.getPageNum(),param.getPageSize());
        lst2 = studentZuoyeMapper.list(param);
        PageHelper.clearPage();

        PageInfo<StudentZuoye> pi1 = new PageInfo<>(lst2);


        // 完善 ，遍历 lst1 里面的 student_group_id ，更新 studentGroupName
        lst2.forEach((stzy)->{
            String stgroupId = stzy.getStudent_group_id();
            if(StringUtils.isEmpty(stgroupId)){
                return;
            }
            StudentGroup stgp1 = new StudentGroup();
            stgp1.setNoid(stgroupId);
            StudentGroup stgp2 = studentGroupMapper.get(stgp1);
            if(stgp2!=null){
                stzy .setStudentGroupName(stgp2.getStudent_group_name());
            }
        });

        return ResultBean.create(0,"success",pi1);
    }

    /**
     * 删除学生的某条作业
     * @param parm
     * @return
     */
    public ResultBean<PageInfo<StudentZuoye>> delete(StudentZuoye parm) {
        StudentZuoye studentZuoye = studentZuoyeMapper.get(parm);
        String filePath = globalSet.getZuoye_upload_root_path()+"/zuoye/"+studentZuoye.getZuoye_file_path();
        File file = new File(filePath);

        for (int i = 0; i < 5; i++) {
            boolean result =  file.delete();
            if(!result){
                System.gc();
                file.delete();
            }
        }

        studentZuoyeMapper.delete(parm);
        return ResultBean.create(0, "success");
    }

    /**
     * 修改学生的某条作业
     * @param parm
     * @return
     */
    public ResultBean<PageInfo<StudentZuoye>> update(StudentZuoye parm) {
        StudentZuoye stu = new StudentZuoye();
        stu.setNoid(parm.getNoid());
        Integer i1 = 0;
        if (stu.getNoid() != null) {
            stu.setWancheng_status(parm.getWancheng_status());
            i1 = studentZuoyeMapper.update(stu);
        }
        return ResultBean.create(0, "success", i1);
    }

    /**
     * 对全表登记页面进行分页
     * @param param
     * @return
     */
    public ResultBean<PageInfo<FullTableStudentZuoye>> pageForFullTable(FullTableStudentZuoye param) {

        // 1 读取相关的布置作业

        BuzhiZuoye bzzy1 = new BuzhiZuoye();
        bzzy1.setSearchKey(param.getSearchKey());

        PageHelper.startPage(param.getPageNum(),param.getPageSize());
        List<FullTableStudentZuoye> lstBzzy1 = buzhiZuoyeMapper.listForFullTable(bzzy1);
        PageInfo<FullTableStudentZuoye> piBzzy1 = new PageInfo<>(lstBzzy1);
        PageHelper.clearPage();

        // 2 对每个布置作业，添加学生完成情况数据
        lstBzzy1.forEach((ftstzy)->{

            // 2.1 读取学生完成情况
            StudentZuoye stzy3= new StudentZuoye();
            stzy3.setBuzhi_zuoye_id(ftstzy.getBuzhi_zuoye_id());
            List<StudentZuoye> stzy3Res = studentZuoyeMapper.list(stzy3);
            ftstzy.setStudentZuoyeList(stzy3Res);

            // 2.2 将学生作业完成情况 List 转换为Map
            stzy3Res.forEach((stzy4)->{
                ftstzy.getStudentZuoyeMap().put(stzy4.getStudent_id(), stzy4);
            });

            // 2.3 更新每个作业的完成数量
            ftstzy.setAllCount(12);
            ftstzy.setNoExamCount(2);
            ftstzy.setYiwanchengCount(9);
            ftstzy.setWeiwanchengCount(1);


        });

        return ResultBean.create(0,"success", piBzzy1);

    }

    /**
     * 读取下载作业的路径
     * @param param
     * @return
     */
    public ResultBean<String> download_path(StudentZuoye param) {
        param.setDownload_path(globalSet.getZuoyu_upload_url_root() + "zuoye");
        return ResultBean.create(0,"success", param);
    }

    /**
     * 查看解压后的作业，生成树形结构
     * @param parm
     * @return
     */
    public ResultBean<PageInfo<StudentZuoye>> zuoyeView(StudentZuoye parm) {
        StudentZuoye stuZuoye = studentZuoyeMapper.get(parm);
        String filePath = globalSet.getZuoye_upload_root_path() + "/zuoye/" + stuZuoye.getZuoye_file_path();
        File file = new File(filePath);
        logger.debug(filePath);
        String outPath = "";
        List<Map<String, Object>> treeList = null;
        if (file.exists()) {
            try {
                outPath = globalSet.getZuoye_upload_root_path() + "/unZipFiles/" + stuZuoye.getUnzip_path();
                treeList = creatFileTree(new File(outPath));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return ResultBean.create(0, "success", treeList);
    }

    /**
     * 上传的作业的文件路径，指定上传文件为zip，并对上传的文件进行解压
     * @param param
     * @param uploadFile1
     * @return
     * @throws IOException
     */
    public ResultBean<Integer> filePath(Map<String,String> param, MultipartFile uploadFile1) throws IOException {
        InputStream inputStream = uploadFile1.getInputStream();
        String fileName = uploadFile1.getOriginalFilename();
        if (fileName.contains(".zip")){

            //获取上传的文件名称
            StudentZuoye studentZuoye = new StudentZuoye();
            studentZuoye.setNoid(param.get("noid"));
            StudentZuoye s2 = studentZuoyeMapper.get(studentZuoye);
            //为null就上传
            //C://zuoye_upload/zuoye
            String filePath = globalSet.getZuoye_upload_root_path() + "/zuoye";
            Map<String, String> map = PbFileUtils.getFilePath(filePath, uploadFile1);
            String fullPath = null;
            String realPath = null;
            if (s2.getZuoye_file_path() == null) {
                fullPath = map.get("fullPath");
                realPath = map.get("realPath");
            } else {
                //不为null就将文件名取出，再将上传的文件名修改为数据库中存在的文件名
                fullPath = filePath + "/" + s2.getZuoye_file_path();
                realPath = s2.getZuoye_file_path();
            }
            //保存文件
            PbFileUtils.saveFile(fullPath,inputStream);

            //上传作业后将作业的路径保存到数据库中
            s2.setZuoye_file_path(realPath);
            //解压文件到指定路径
            //通用的解压后的文件路径，例：C:/zuoye-unload/unZipFiles/
            String allUnFilePath = globalSet.getZuoye_upload_root_path() + "/unZipFiles/";
            //获取当前上传后解压的文件路径
            String unZipPath = s2.getUnzip_path();
            //如果解压后的文件路径不为null
            if (unZipPath != null) {
                //删除之前解压的文件，替换为当前最新上传的文件路径
                PbFileUtils.delUnFiles(new  File(allUnFilePath + unZipPath));
            }
            //文件原路径
            String filePath2 = globalSet.getZuoye_upload_root_path() + "/zuoye/" + s2.getZuoye_file_path();
            String fileDatePath = PbFileUtils.createFileDatePath();
            String finalPath = allUnFilePath+fileDatePath+"/"+s2.getNoid()+"/";
            File file = new File(filePath2);
            //将文件解压到指定的路径
            unZipFiles(file, finalPath);
            //将解压后的路径保存到数据库
            s2.setUnzip_path(fileDatePath+"/"+s2.getNoid());
            String str = PbFileUtils.createFileDatePath();
            s2.setSubmit_time(new Date());
            studentZuoyeMapper.update(s2);
            inputStream.close();


            return ResultBean.create(0,"success");
        }
        return ResultBean.create(10, "只能上传zip文件！");
    }

    /**
     * 得到某条作业的信息
     * @param param
     * @return
     */
    public ResultBean<String> zuoye_get(StudentZuoye param){
        StudentZuoye stu = studentZuoyeMapper.get(param);
        BuzhiZuoye buzhiZuoye = new BuzhiZuoye();
        buzhiZuoye.setNoid(stu.getBuzhi_zuoye_id());
        buzhiZuoye = buzhiZuoyeMapper.get(buzhiZuoye);
        List<String> lst = new ArrayList<>();
        lst.add(stu.getStudent_realname());
        lst.add(stu.getBuzhi_zuoye_title());
        lst.add(buzhiZuoye.getZuoye_detail());
        lst.add(stu.getBuzhi_date().toLocaleString());
        if (stu.getSubmit_time() != null) {
            lst.add(stu.getSubmit_time().toLocaleString());
        }
        return ResultBean.create(0,"success", lst);
    }

    /**
     * 获取解压缩完成文件后的所有文件，并生成树形结构
     * */
    public List<Map<String, Object>> creatFileTree(File file) throws IOException {
        List<Map<String, Object>> lst = new ArrayList<>();
        //[{label: "大数据专业3-第14单元日考题", children:[{label:""}]}]
        File[] files = file.listFiles();
        if(files != null){
            for (File f1 : files) {
                Map<String, Object> maps = new HashMap<>();
                maps.put("label", f1.getName());
                String url1 = f1.getAbsolutePath();
                String url3 = url1.substring(globalSet.getZuoye_upload_root_path().length());
                String url2 = globalSet.getZuoyu_upload_url_root() + url3;
                Path path = f1.toPath();
                String mimeType = Files.probeContentType(path);
                if ( !StringUtils.isEmpty(mimeType) && mimeType.contains("text")) {
                    maps.put("url", url2);
                    try {
//                        //获取文件的编码格式
//                        String unicode = PbFileUtils.codeString(url1);
//                        //如果文件是jsp文件，设置编码为utf-8
//                        if (StringUtils.isEmpty(unicode)){
//                            unicode = "GBK";
//                        }
//                        maps.put("unicode", unicode);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                if (url1.contains("xml") || url1.contains("sql")) {
                    maps.put("url", url2);
                }

                maps.put("directory",0);
                if (f1.isDirectory()) {
                    List<Map<String, Object>> list = creatFileTree(f1);
                    if (list.size() > 0) {
                        maps.put("children", list);
                        maps.put("directory",1);
                    }
                }
                lst.add(maps);
            }
        }
        if (file.isFile()) {
            Map<String, Object> maps = new HashMap<>();
            maps.put("label", file.getName());
            String url1 = file.getAbsolutePath();
            String url3 = url1.substring(globalSet.getZuoye_upload_root_path().length());
            String url2 = globalSet.getZuoye_upload_root_path() + url3;
            maps.put("url", url2);
            lst.add(maps);
        }
        return lst;
    }

    /**
     * 解压文件到指定目录
     */
    static int count = 0;
    @SuppressWarnings("rawtypes")
    public static String unZipFiles(File zipFile,String descDir)throws IOException
    {

        String getUnfilePath = "";
        //解决zip文件中有中文目录或者中文文件
        ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
        for(Enumeration entries = zip.entries(); entries.hasMoreElements();)
        {
            ZipEntry entry = (ZipEntry)entries.nextElement();
            String zipEntryName = entry.getName();
            InputStream in = zip.getInputStream(entry);
            if(count == 0){
                String str1 = zipEntryName.substring(0, zipEntryName.length());
                getUnfilePath = descDir+str1;
                count++;
            }
            String outPath = (descDir+zipEntryName).replaceAll("\\*", "/");;
            //判断路径是否存在,不存在则创建文件路径
            File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
            if(!file.exists())
            {
                file.mkdirs();
            }
            //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
            if(new File(outPath).isDirectory())
            {
                continue;
            }
            //输出文件路径信息
            OutputStream out = new FileOutputStream(outPath);
            byte[] buf1 = new byte[1024];
            int len;
            while((len=in.read(buf1))>0)
            {
                out.write(buf1,0,len);
            }
            in.close();
            out.close();

        }
        count = 0;
        return getUnfilePath;
    }

    /**
     * 评论某条作业的信息
     * @param param
     * @return
     */

    public ResultBean<String> commentMsg(Comment param) {
        String noid = "";
        try {
            param.setNoid(PbSecretUtils.uuid());
            param.setComment_message_state(1);
            commentMapper.insert(param);
            StudentZuoye studentZuoye = new StudentZuoye();
            studentZuoye.setNoid(param.getComment_zuoye_noid());
            studentZuoye = studentZuoyeMapper.get(studentZuoye);
            Student student = new Student();
            student.setNoid(studentZuoye.getStudent_id());
            student = studentMapper.get(student);
            UserInfo userInfo = new UserInfo();
            userInfo.setUsercode(student.getBind_usercode());
            userInfo = userInfoMapper.get(userInfo);
            noid = userInfo.getNoid();
        } catch (Exception err) {
            return ResultBean.create(23, err.getMessage());
        }
        return ResultBean.create(0,"success", noid);
    }

    /**
     * 得到作业的评论信息
     * @param param
     * @return
     */
    public ResultBean<List<Comment>> getComment(Comment param) {
        List<Comment> commentList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            commentList = commentMapper.list(param);
            for(Comment comment : commentList){
                //根据comment的noid 拿到该评论下的回复
                Revert revert = new Revert();
                revert.setComment_noid(comment.getNoid());
                List<Revert> revertList = revertMapper.list(revert);
                //获取回复人的真实姓名，并存入回复类
                for (Revert revert1 : revertList) {
                    UserInfo userInfo = new UserInfo();
                    userInfo.setNoid(revert1.getUser_noid());
                    userInfo = userInfoMapper.get(userInfo);
                    //设置姓名
                    revert1.setRealname(userInfo.getRealname());
                    revert1.setStr_revert_date(sdf.format(revert1.getRevert_date()));
                }
                comment.setStr_comment_date(sdf.format(comment.getComment_date()));
                comment.setRevertList(revertList);
            }
        } catch (Exception err) {
            return ResultBean.create(23, err.getMessage());
        }

        return ResultBean.create(0,"success", commentList);
    }

    /**
     * 删除某条评论信息
     * @param param
     * @return
     */
    public ResultBean<Integer> delCommentMsg(Comment param) {
        //根据Comment的noid去删除
        commentMapper.delete(param);
        //把这条评论所关联的回复也要删除
        Revert revert = new Revert();
        revert.setComment_noid(param.getNoid());
        revertMapper.delete(revert);

        return ResultBean.create(0,"success", 0);
    }

    /**
     * 回复某条作业的信息
     * @param param
     * @return
     */
    public ResultBean<Integer> revertMsg(Revert param){
        param.setNoid(PbSecretUtils.uuid());
        param.setRevert_message_state(1);
        revertMapper.insert(param);
        return  ResultBean.create(0,"success",0);
    }

    /**
     * 删除作业的某条回复信息
     * @param param
     * @return
     */
    public ResultBean<Integer> delRevertMsg(Revert param) {
        revertMapper.delete(param);
        return ResultBean.create(0,"success", 0);
    }


}
